/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include <iostream>
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "stub.h"
#include "ApplicationProtectPlugin_types.h"
#include "ApplicationProtectBaseDataType_types.h"
#include "restore/ReplicationRestoreJob.h"
#include "ClientInvoke.h"
#include "PluginUtilities.h"
#include "device_access/ControlDevice.h"

using ::testing::_;
using testing::AllOf;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using testing::ByMove;
using testing::DoAll;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Ge;
using ::testing::Gt;
using testing::InitGoogleMock;
using ::testing::Invoke;
using ::testing::Ne;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgReferee;
using ::testing::SetArgumentPointee;
using ::testing::Throw;
using namespace NasRepServiceObjOp;
using namespace AppProtect;
using namespace std;
using namespace Module;

class ReplicationRestoreJobTest : public testing::Test {
public:
    void SetUp();
    void TearDown() {}
    static void SetUpTestCase() {}
    static void TearDownTestCase() {}
    Stub stub;
    std::shared_ptr<DoradoNas> m_localController;
    std::shared_ptr<DoradoNas> m_remoteController;
    std::unique_ptr<ReplicationRestoreJob> m_nasReplicationRestoreJob;
};

static AppProtect::RestoreJob RestoreJobSetup()
{
    RestoreJob homoRestoreJob;
    homoRestoreJob.jobId = "main_job_id_000";
    homoRestoreJob.requestId = "000001";
    homoRestoreJob.targetEnv.__isset.auth = true;
    homoRestoreJob.targetEnv.auth.__set_authkey("admin");
    homoRestoreJob.targetEnv.auth.__set_authPwd("Admin@123");
    homoRestoreJob.targetEnv.__set_endpoint("8.40.102.115");
    homoRestoreJob.targetEnv.__set_port(8088);
    homoRestoreJob.targetEnv.extendInfo = "{\"snapConsistency\":\"0\",\"verifyStatus\":\"1\",\"wwn\":\"\"}";
    homoRestoreJob.targetEnv.auth.extendInfo = "{\"fingerPrint\" : \"4928EBB6E58A3A395BC89317DD55B82F1B8C10E7\"}";
    homoRestoreJob.targetObject.__set_id("147");
    homoRestoreJob.targetObject.__set_name("test_123456");
    homoRestoreJob.targetObject.__set_extendInfo("{\"tenantName\":\"d0\", \"fileSystemId\":\"148\", \"usedCapacity\":\"5986\", \"onlineStatus\":\"1\", \"tenantId\":\"15\", \"capacity\":\"123456789\"}");
    StorageRepository storage;
    storage.__isset.auth = true;
    storage.__isset.endpoint = true;

    storage.repositoryType = RepositoryDataType::type::DATA_REPOSITORY;
    storage.auth.__set_authkey("admin");
    storage.auth.__set_authPwd("Admin@123");
    storage.endpoint.ip = "8.40.102.105,8.40.102.106";
    storage.endpoint.port = 8088;
    storage.__set_remotePath("/Storage_1234/123456789");

    StorageRepository storage2;
    storage2.__isset.auth = true;
    storage2.__isset.endpoint = true;

    storage2.repositoryType = RepositoryDataType::type::META_REPOSITORY;
    storage2.auth.__set_authkey("admin");
    storage2.auth.__set_authPwd("Admin@123");
    storage2.endpoint.ip = "8.40.102.105,8.40.102.106";
    storage2.endpoint.port = 8088;
    storage2.__set_remotePath("/Storage_1234/123456789");
    vector<string> path {"/home"};
    storage2.__set_path(path);

    Snapshot snap;
    snap.id = "1";
    snap.parentName = "test";

    Copy copy;
    copy.name = "pppp";
    copy.repositories.push_back(storage);
    copy.repositories.push_back(storage2);
    copy.snapshots.push_back(snap);
    homoRestoreJob.copies.push_back(copy);
    return homoRestoreJob;
}

static void returnVoidStub(void* obj)
{
    return;
}

void ReplicationRestoreJobTest::SetUp() {
    stub.set(sleep, returnVoidStub);
    m_nasReplicationRestoreJob = std::make_unique<ReplicationRestoreJob>();
    SubJob subJob;
    // subJobId keyword is optional, this operation is necessary
    subJob.__isset.subJobId = true;
    subJob.__set_jobId("sub_job_id");
    subJob.jobId = "jobId123";
    subJob.subJobId = "subJob123";
    subJob.jobName = "XYZ";
    subJob.jobPriority = 1;
    subJob.jobInfo = "{\"ControlFile\":\"\",\"SubTaskType\":1,\"Ext\":\"\"}";

    // test BackupPrerequisiteJob
    AppProtect::RestoreJob homoRestoreJob = RestoreJobSetup();
    auto jobInfo = make_shared<JobCommonInfo>(make_shared<RestoreJob>(homoRestoreJob));
    m_nasReplicationRestoreJob->SetJobInfo(jobInfo);
    m_nasReplicationRestoreJob->m_restorePara = make_shared<RestoreJob>(homoRestoreJob);
    std::shared_ptr <SubJob> subJobptr = std::make_shared<SubJob>(subJob);
    m_nasReplicationRestoreJob->SetSubJob(subJobptr);

    ControlDeviceInfo basicDeviceInfo;
    basicDeviceInfo.deviceName = "test";  // 文件系统名称在pair预处理过程中或者新创pair时会设置，此处不需要
    basicDeviceInfo.url = "";   // 使用安全IP登录，不需要IP和端口号
    basicDeviceInfo.port = "";  // 使用安全IP登录，不需要IP和端口号
    basicDeviceInfo.userName = "admin";
    basicDeviceInfo.password = "Huawei@123";
    basicDeviceInfo.poolId = 0;
    basicDeviceInfo.compress = false;
    basicDeviceInfo.dedup = false;
    basicDeviceInfo.poolId = 0;
    std::string m_productFSID = "1";
    m_localController = std::make_unique<DoradoNas>(basicDeviceInfo, false);
    m_remoteController = std::make_unique<DoradoNas>(basicDeviceInfo, m_productFSID, false);
    m_nasReplicationRestoreJob->m_localDeviceController = std::make_unique<DoradoNas>(basicDeviceInfo, m_productFSID, false);
    m_nasReplicationRestoreJob->m_remoteDeviceController = std::make_unique<DoradoNas>(basicDeviceInfo, m_productFSID, false);
}

static bool InitDeviceInfoMethodSuc_Stub(void* obj)
{
    return true;
}

static bool InitDeviceInfoMethodFail_Stub(void* obj)
{
    return false;
}

static bool IsReportAgentErrorCodeSuc_Stub(void* obj, LogDetail logDetail)
{
    return true;
}

static bool IsReportAgentErrorCodeFail_Stub(void* obj, LogDetail logDetail)
{
    return false;
}

/**
 * 用例名称：PostJobInner_InitDeviceFail
 * 前置条件：无
 * check点：postJob->初始化设备失败
 */
TEST_F(ReplicationRestoreJobTest, PostJobInner_InitDeviceFail)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodFail_Stub);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeFail_Stub);
    int result = m_nasReplicationRestoreJob->PostJobInner();
    EXPECT_EQ(result, MP_FAILED);

    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeSuc_Stub);
    result = m_nasReplicationRestoreJob->PostJobInner();
    EXPECT_EQ(result, MP_FAILED);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

static bool ConfirmRestoreLocationSuc_Stub(void* obj, RestoreLocation &restoreLocation)
{
    return true;
}

static bool ConfirmRestoreLocationFail_Stub(void* obj, RestoreLocation &restoreLocation)
{
    return false;
}

/**
 * 用例名称：PostJobInner_ConfirmRestoreLocationFail
 * 前置条件：无
 * check点：postJob->初始化设备失败
 */
TEST_F(ReplicationRestoreJobTest, PostJobInner_ConfirmRestoreLocationFail)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodSuc_Stub);
    stub.set(ADDR(ReplicationRestoreJob, ConfirmRestoreLocation), ConfirmRestoreLocationFail_Stub);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeSuc_Stub);
    int result = m_nasReplicationRestoreJob->PostJobInner();
    EXPECT_EQ(result, MP_FAILED);

    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeFail_Stub);
    result = m_nasReplicationRestoreJob->PostJobInner();
    EXPECT_EQ(result, MP_FAILED);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(ReplicationRestoreJob, ConfirmRestoreLocation));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

static bool DeletePairWhenRestoreSuc_Stub(void* obj, RestoreLocation &restoreLocation)
{
    return true;
}

static bool DeletePairWhenRestoreFail_Stub(void* obj, RestoreLocation &restoreLocation)
{
    return false;
}

/**
 * 用例名称：PostJobInner_ALL
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, PostJobInner_ALL)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodSuc_Stub);
    stub.set(ADDR(ReplicationRestoreJob, ConfirmRestoreLocation), ConfirmRestoreLocationSuc_Stub);
    stub.set(ADDR(ReplicationRestoreJob, DeletePairWhenRestore), DeletePairWhenRestoreFail_Stub);
    int result = m_nasReplicationRestoreJob->PostJobInner();
    EXPECT_EQ(result, MP_FAILED);

    stub.set(ADDR(ReplicationRestoreJob, DeletePairWhenRestore), DeletePairWhenRestoreSuc_Stub);
    result = m_nasReplicationRestoreJob->PostJobInner();
    EXPECT_EQ(result, MP_SUCCESS);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(ReplicationRestoreJob, ConfirmRestoreLocation));
    stub.reset(ADDR(ReplicationRestoreJob, DeletePairWhenRestore));
}

static bool UpdateDeviceFail_Stub(void* obj, ControlDeviceInfo &deviceInfo,const std::vector<std::string> &mgrIpList)
{
    return false;
}

static bool UpdateDeviceSuc_Stub(void* obj, ControlDeviceInfo &deviceInfo,const std::vector<std::string> &mgrIpList)
{
    return true;
}

/**
 * 用例名称：UpdateBasicDeviceInfo_Fail
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, UpdateBasicDeviceInfo_Fail)
{
    ControlDeviceInfo basicDeviceInfo;
    stub.set(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP), UpdateDeviceFail_Stub);
    bool result = m_nasReplicationRestoreJob->UpdateBasicDeviceInfo(basicDeviceInfo);
    EXPECT_EQ(result, false);
    stub.reset(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP));
}

static bool GetMgrIpFromExtFail_Stub(void* obj, std::vector<std::string>& ipList, const std::string& extInfo)
{
    return false;
}

static bool GetMgrIpFromExtSuc_Stub(void* obj, std::vector<std::string>& ipList, const std::string& extInfo)
{
    return true;
}

static bool CertVerifyMgrFail_Stub(void* obj, const ApplicationEnvironment& protectEnv,
                                   ControlDeviceInfo& productDeviceInfo)
{
    return false;
}

static bool CertVerifyMgrSuc_Stub(void* obj, const ApplicationEnvironment& protectEnv,
                                  ControlDeviceInfo& productDeviceInfo)
{
    return true;
}

/**
 * 用例名称：UpdateProductDeviceInfo
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, UpdateProductDeviceInfo)
{
    ControlDeviceInfo basicDeviceInfo;
    stub.set(ADDR(ReplicationCommonService, GetMgrIpFromExt), GetMgrIpFromExtFail_Stub);
    bool result = m_nasReplicationRestoreJob->UpdateProductDeviceInfo(basicDeviceInfo);
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationCommonService, GetMgrIpFromExt), GetMgrIpFromExtSuc_Stub);
    stub.set(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP), UpdateDeviceFail_Stub);
    result = m_nasReplicationRestoreJob->UpdateProductDeviceInfo(basicDeviceInfo);
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP), UpdateDeviceSuc_Stub);
    typedef bool (*fptr)(ReplicationCommonService*, const ApplicationEnvironment&,ControlDeviceInfo&);
    fptr ReplicationRestoreJob_CertVerifyMgr = (fptr)(&ReplicationCommonService::CertVerifyMgr);
    stub.set(ReplicationRestoreJob_CertVerifyMgr, CertVerifyMgrFail_Stub);
    result = m_nasReplicationRestoreJob->UpdateProductDeviceInfo(basicDeviceInfo);
    EXPECT_EQ(result, false);

    stub.set(ReplicationRestoreJob_CertVerifyMgr, CertVerifyMgrSuc_Stub);
    result = m_nasReplicationRestoreJob->UpdateProductDeviceInfo(basicDeviceInfo);
    EXPECT_EQ(result, true);

    stub.reset(ADDR(ReplicationCommonService, GetMgrIpFromExt));
    stub.reset(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP));
    stub.reset(ADDR(ReplicationCommonService, CertVerifyMgr));
}

/**
 * 用例名称：InitializeTask_InitDeviceInfoFail
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, InitializeTask_InitDeviceInfoFail)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodFail_Stub);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeSuc_Stub);
    bool result = m_nasReplicationRestoreJob->InitializeTask();
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeFail_Stub);
    result = m_nasReplicationRestoreJob->InitializeTask();
    EXPECT_EQ(result, false);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

static int GetESNSuc_Stub(void* obj)
{
    return Module::SUCCESS;
}

static int GetESNFail_Stub(void* obj)
{
    return Module::FAILED;
}

static NasRepServiceObjOp::NasReplicationServiceErrorCode PrepareRemoteReplicatonPairMethodSuc_Stub(void* obj)
{
    return NasRepServiceObjOp::NasReplicationServiceErrorCode::ReplicationServiceNormal;
}

/**
 * 用例名称：InitializeTask_Suc
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, InitializeTask_Suc)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodSuc_Stub);
    stub.set(ADDR(DoradoNas, GetESN), GetESNSuc_Stub);
    stub.set(ADDR(NasRepServiceObjOp::NasReplicationService, PrepareRemoteReplicatonPair),
             PrepareRemoteReplicatonPairMethodSuc_Stub);
    bool result = m_nasReplicationRestoreJob->InitializeTask();
    EXPECT_EQ(result, true);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(DoradoNas, GetESN));
    stub.reset(ADDR(NasRepServiceObjOp::NasReplicationService, PrepareRemoteReplicatonPair));
}

/**
 * 用例名称：InitializeTask_GetEsnFail
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, InitializeTask_GetEsnFail)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodSuc_Stub);
    stub.set(ADDR(DoradoNas, GetESN), GetESNFail_Stub);
    stub.set(ADDR(NasRepServiceObjOp::NasReplicationService, PrepareRemoteReplicatonPair),
            PrepareRemoteReplicatonPairMethodSuc_Stub);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeSuc_Stub);
    bool result = m_nasReplicationRestoreJob->InitializeTask();
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeFail_Stub);
    result = m_nasReplicationRestoreJob->InitializeTask();
    EXPECT_EQ(result, false);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(DoradoNas, GetESN));
    stub.reset(ADDR(NasRepServiceObjOp::NasReplicationService, PrepareRemoteReplicatonPair));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

static bool GetJobInfoBodyFail_Stub(void* obj)
{
    return false;
}

static bool GetJobInfoBodySuc_Stub(void* obj)
{
    return true;
}

int callCheckCertThumbPrintFail_Stub(void* obj, const AppProtect::ApplicationEnvironment& targetEnv)
{
    return MP_FAILED;
}

int callCheckCertThumbPrintSuc_Stub(void* obj, const AppProtect::ApplicationEnvironment& targetEnv)
{
    return MP_SUCCESS;
}

static bool UpdateBasicDeviceInfoFail_Stub(void* obj, ControlDeviceInfo &basicDeviceInfo)
{
    return false;
}

static bool UpdateBasicDeviceInfoSuc_Stub(void* obj, ControlDeviceInfo &basicDeviceInfo)
{
    return true;
}

/**
 * 用例名称：InitDeviceInfo_PreFail
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, InitDeviceInfo_PreFail)
{
    stub.set(ADDR(ReplicationRestoreJob, GetJobInfoBody), GetJobInfoBodyFail_Stub);
    bool result = m_nasReplicationRestoreJob->InitDeviceInfo();
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationRestoreJob, GetJobInfoBody), GetJobInfoBodySuc_Stub);
    stub.set(ADDR(ReplicationRestoreJob, callCheckCertThumbPrint), callCheckCertThumbPrintFail_Stub);
    result = m_nasReplicationRestoreJob->InitDeviceInfo();
    EXPECT_EQ(result, false);

    stub.reset(ADDR(ReplicationRestoreJob, GetJobInfoBody));
    stub.reset(ADDR(ReplicationRestoreJob, callCheckCertThumbPrint));
}

static int QuerySnapshotSuc_Stub(void* obj, std::string SnapshotName, std::string &id)
{
    return Module::SUCCESS;
}

static int QuerySnapshotFail_Stub(void* obj, std::string SnapshotName, std::string &id)
{
    return Module::FAILED;
}

static bool UpdateProductDeviceInfoFail_Stub(void* obj, ControlDeviceInfo &basicDeviceInfo)
{
    return false;
}

static bool UpdateProductDeviceInfoSuc_Stub(void* obj, ControlDeviceInfo &basicDeviceInfo)
{
    return true;
}

/**
 * 用例名称：InitDeviceInfo_NextFail
 * 前置条件：无
 * check点：postJob完整流程
 */
// TEST_F(ReplicationRestoreJobTest, InitDeviceInfo_NextFail)
// {
//     stub.set(ADDR(ReplicationRestoreJob, GetJobInfoBody), GetJobInfoBodySuc_Stub);
//     stub.set(ADDR(ReplicationRestoreJob, callCheckCertThumbPrint), callCheckCertThumbPrintSuc_Stub);
//     typedef bool (*fptr)(ReplicationRestoreJob*, ControlDeviceInfo&);
//     fptr ReplicationRestoreJob_UpdateBasicDeviceInfo = (fptr)(&ReplicationRestoreJob::UpdateBasicDeviceInfo);
//     stub.set(ReplicationRestoreJob_UpdateBasicDeviceInfo, UpdateBasicDeviceInfoFail_Stub);
//     bool result = m_nasReplicationRestoreJob->InitDeviceInfo();
//     EXPECT_EQ(result, false);

//     stub.set(ReplicationRestoreJob_UpdateBasicDeviceInfo, UpdateBasicDeviceInfoSuc_Stub);
//     stub.set(ADDR(DoradoNas, QuerySnapshot), QuerySnapshotFail_Stub);
//     result = m_nasReplicationRestoreJob->InitDeviceInfo();
//     EXPECT_EQ(result, false);

//     stub.set(ADDR(DoradoNas, QuerySnapshot), QuerySnapshotSuc_Stub);
//     typedef bool (*fptr2)(ReplicationRestoreJob*, ControlDeviceInfo&);
//     fptr2 ReplicationRestoreJob_UpdateProductDeviceInfo = (fptr2)(&ReplicationRestoreJob::UpdateProductDeviceInfo);
//     stub.set(ReplicationRestoreJob_UpdateProductDeviceInfo, UpdateProductDeviceInfoFail_Stub);
//     result = m_nasReplicationRestoreJob->InitDeviceInfo();
//     EXPECT_EQ(result, false);

//     stub.set(ReplicationRestoreJob_UpdateProductDeviceInfo, UpdateProductDeviceInfoSuc_Stub);
//     result = m_nasReplicationRestoreJob->InitDeviceInfo();
//     EXPECT_EQ(result, true);

//     stub.reset(ADDR(ReplicationRestoreJob, GetJobInfoBody));
//     stub.reset(ADDR(ReplicationRestoreJob, callCheckCertThumbPrint));
//     stub.reset(ADDR(ReplicationRestoreJob, UpdateBasicDeviceInfo));
//     stub.reset(ADDR(DoradoNas, QuerySnapshot));
// }

/**
 * 用例名称：callCheckCertThumbPrint
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, callCheckCertThumbPrint)
{
    const AppProtect::ApplicationEnvironment targetEnv;
    int result = m_nasReplicationRestoreJob->callCheckCertThumbPrint(targetEnv);
    EXPECT_EQ(result, MP_FAILED);
}

/**
 * 用例名称：PreStartTask_InitDeviceInfoFail
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, PreStartTask_InitDeviceInfoFail)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodFail_Stub);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeSuc_Stub);
    stub.set(ADDR(ReplicationCommonService, WaitingOtherReplicationPairComplete), IsReportAgentErrorCodeSuc_Stub);
    bool result = m_nasReplicationRestoreJob->PreStartTask();
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeFail_Stub);
    result = m_nasReplicationRestoreJob->PreStartTask();
    EXPECT_EQ(result, false);

    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
    stub.reset(ADDR(ReplicationCommonService, WaitingOtherReplicationPairComplete));
    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
}

static bool GetPairInfoInProductSuc_Stub(void* obj)
{
    return true;
}

static bool GetPairInfoInProductFail_Stub(void* obj)
{
    return false;
}

/**
 * 用例名称：PreStartTask_GetPairInfoInProductFail
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, PreStartTask_GetPairInfoInProductFail)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodSuc_Stub);
    stub.set(ADDR(DoradoNas, GetESN), GetESNSuc_Stub);
    stub.set(ADDR(NasRepServiceObjOp::NasReplicationService, GetPairInfoInProduct),GetPairInfoInProductFail_Stub);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeSuc_Stub);
    bool result = m_nasReplicationRestoreJob->PreStartTask();
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCodeFail_Stub);
    result = m_nasReplicationRestoreJob->PreStartTask();
    EXPECT_EQ(result, false);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(DoradoNas, GetESN));
    stub.reset(ADDR(NasRepServiceObjOp::NasReplicationService, GetPairInfoInProduct));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

static bool RevertSnapShotInStorageSuc_Stub(void* obj)
{
    return true;
}

static bool RevertSnapShotInStorageFail_Stub(void* obj)
{
    return false;
}

/**
 * 用例名称：PreStartTask
 * 前置条件：无
 * check点：postJob完整流程
 */
TEST_F(ReplicationRestoreJobTest, PreStartTask)
{
    typedef bool (*fptr)(ReplicationRestoreJob*);
    fptr ReplicationRestoreJob_InitDeviceInfo = (fptr)(&ReplicationRestoreJob::InitDeviceInfo);
    stub.set(ReplicationRestoreJob_InitDeviceInfo, InitDeviceInfoMethodSuc_Stub);
    stub.set(ADDR(DoradoNas, GetESN), GetESNSuc_Stub);
    stub.set(ADDR(NasRepServiceObjOp::NasReplicationService, GetPairInfoInProduct),GetPairInfoInProductSuc_Stub);
    stub.set(ADDR(ReplicationRestoreJob, RevertSnapShotInStorage), RevertSnapShotInStorageFail_Stub);
    bool result = m_nasReplicationRestoreJob->PreStartTask();
    EXPECT_EQ(result, false);

    stub.set(ADDR(ReplicationRestoreJob, RevertSnapShotInStorage), RevertSnapShotInStorageSuc_Stub);
    stub.set(ADDR(ReplicationCommonService, WaitingOtherReplicationPairComplete), callCheckCertThumbPrintSuc_Stub);
    result = m_nasReplicationRestoreJob->PreStartTask();
    EXPECT_EQ(result, true);

    stub.reset(ADDR(ReplicationRestoreJob, InitDeviceInfo));
    stub.reset(ADDR(DoradoNas, GetESN));
    stub.reset(ADDR(ReplicationCommonService, WaitingOtherReplicationPairComplete));
    stub.reset(ADDR(NasRepServiceObjOp::NasReplicationService, GetPairInfoInProduct));
    stub.reset(ADDR(ReplicationRestoreJob, RevertSnapShotInStorage));
}





